
// INCLUDES ********************************************************************

#import "ES1Renderer.h"

#import <OpenGLES/ES1/gl.h>

#import <OpenGLES/ES1/glext.h>



// NAMESPACES ******************************************************************

// *****************************************************************************

@implementation ES1Renderer

#pragma mark -
#pragma mark Object lifecycle
// -----------------------------------------------------------------------------

- ( id)initWithCALayer:( CAEAGLLayer*) layer
{
    self = [super init];
    
    if ( !self)
    {
        return nil;
    }
    
    mLayer = layer;
    
    mGLContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1];
    
    if ( !mGLContext || ![EAGLContext setCurrentContext:mGLContext])
    {
        [self release];
        
        return nil;
    }
    
    return self;
}

// -----------------------------------------------------------------------------

- ( void)dealloc
{
    [self destroyFramebuffers];
    
    if ( [EAGLContext currentContext] == mGLContext) 
    {
        [EAGLContext setCurrentContext:nil];
    }
    
    [mGLContext release];
    
    [super dealloc];
}


#pragma mark -
#pragma mark Buffer creation
// -----------------------------------------------------------------------------

- ( BOOL)createFrameBuffers
{
    GLuint oldRenderbuffer;
	GLuint oldFramebuffer;
    
    glGetIntegerv( GL_RENDERBUFFER_BINDING_OES, ( GLint*) &oldRenderbuffer);
	glGetIntegerv( GL_FRAMEBUFFER_BINDING_OES, ( GLint*) &oldFramebuffer);
    
    glGenRenderbuffersOES( 1, &mRenderbuffer);
    glBindRenderbufferOES( GL_RENDERBUFFER_OES, mRenderbuffer);
    
    glGenFramebuffersOES( 1, &mFramebuffer);
    glBindFramebufferOES( GL_FRAMEBUFFER_OES, mFramebuffer);
    
    const BOOL bufferRendered = [mGLContext renderbufferStorage:GL_RENDERBUFFER_OES
                                                   fromDrawable:mLayer
                                 ];
    
    if ( bufferRendered == NO)
    {
        glDeleteRenderbuffersOES( 1, &mRenderbuffer);
        
        glBindRenderbufferOES( GL_RENDERBUFFER_BINDING_OES, oldRenderbuffer);
        
        return NO;
    }
    
    glFramebufferRenderbufferOES( GL_FRAMEBUFFER_OES, 
                                  GL_COLOR_ATTACHMENT0_OES, 
                                  GL_RENDERBUFFER_OES, 
                                  mRenderbuffer);
    
    const GLenum status = glCheckFramebufferStatusOES( GL_FRAMEBUFFER_OES);
    
    if ( status != GL_FRAMEBUFFER_COMPLETE_OES)
    {
        NSLog( @"Failed to make complete framebuffer RenderObject %x", 
               glCheckFramebufferStatusOES( GL_FRAMEBUFFER_OES));
        
        return NO;
    }
    
    glBindRenderbufferOES( GL_RENDERBUFFER_OES, oldRenderbuffer);
    
    return YES;
}

#pragma mark -
#pragma mark Buffer swap
// -----------------------------------------------------------------------------

- ( void)rendersBuffers
{
	glBindRenderbufferOES( GL_RENDERBUFFER_OES, mRenderbuffer);
    
	if ( ![mGLContext presentRenderbuffer:GL_RENDERBUFFER_OES])
    {
        printf("Failed to swap renderbuffer in %s:\n", __FUNCTION__);
    }

}

#pragma mark -
#pragma mark Buffer deletion
// -----------------------------------------------------------------------------

- ( void)destroyFramebuffers 
{
    glDeleteFramebuffersOES( 1, &mFramebuffer);
    
    mFramebuffer = 0;
    
    glDeleteRenderbuffersOES( 1, &mRenderbuffer);
    
    mRenderbuffer = 0;
}

@end


